﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using ExplemKeys.API;
using System.Runtime.InteropServices;
using System.Collections;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;

namespace ExplemKeys.Warcraft
{
    public partial class ExplemWarcaraft : Form
    {

        KeyboardHook hook = new KeyboardHook();
        private const string config = "config.dat";

        private bool isHookEnable = true;

        private const int KEY_QUOTLEFT = 219;//键盘上 [ 键的代码
        private const int KEY_QUOTRIGHT = 221;//键盘上 ] 键的代码

        private const uint WM_SETTEXT = 0x000C;
        private const uint WM_CHAR = 0x0102;
        private const uint EM_SETSEL = 0x00B1;

        private const int WM_CLOSE = 0x10;
        private const int WM_KEYDOWN = 0x100;
        private const int WM_KEYUP = 0x101;


        public ExplemWarcaraft()
        {
            InitializeComponent();
        }

        private void ExplemWarcaraft_Load(object sender, EventArgs e)
        {
           
            hook.OnKeyDownEvent += new KeyEventHandler(hook_OnKeyDownEvent);
            if (File.Exists(config))
            {
                try
                {
                    FileStream fs = new FileStream(config, FileMode.Open, FileAccess.Read);
                    BinaryFormatter bf = new BinaryFormatter();
                    hash = (Hashtable)bf.Deserialize(fs);
                    fs.Close();
                }
                catch { }
            }
            if (hash.Count > 0)
            {
                foreach (DictionaryEntry de in hash)
                {
                    switch (de.Key.ToString())
                    { 
                        case "NumPad1":
                            this.num1.Text = de.Value.ToString();
                            break;
                        case "NumPad2":
                            this.num2.Text = de.Value.ToString();
                            break;
                        case "NumPad4":
                            this.num4.Text = de.Value.ToString();
                            break;
                        case "NumPad5":
                            this.num5.Text = de.Value.ToString();
                            break;
                        case "NumPad7":
                            this.num7.Text = de.Value.ToString();
                            break;
                        case "NumPad8":
                            this.num8.Text = de.Value.ToString();
                            break;
                    }                                  
                }

            }            
            IntPtr hDeskTop = User32Api.FindWindow("Progman", "Program Manager");
            User32Api.SetParent(this.Handle, hDeskTop); //windows+D不会隐藏
        }
       
        private void button1_Click(object sender, EventArgs e)
        {
            hash.Clear();
            if (!string.IsNullOrEmpty(num7.Text))
            {
                hash.Add(((Keys)103).ToString(), this.num7.Text.ToString());
            }
            if (!string.IsNullOrEmpty(num8.Text))
            {
                hash.Add(((Keys)104).ToString(), this.num8.Text.ToString());
            }
            if (!string.IsNullOrEmpty(this.num4.Text))
            {
                hash.Add(((Keys)100).ToString(), this.num4.Text.ToString());
            }
            if(!string.IsNullOrEmpty(this.num5.Text))
            {
              hash.Add(((Keys)101).ToString(),this.num5.Text.ToString());
            }
            if (!string.IsNullOrEmpty(this.num2.Text))
            {
                hash.Add(((Keys)98).ToString(),this.num2.Text.ToString());
            }
            if(!string.IsNullOrEmpty(this.num1.Text))
            {
                hash.Add(((Keys)97).ToString(), this.num1.Text.ToString());
            }
            if (hash.Count > 0)
            {
                try
                {
                    FileStream fs = new FileStream(config, FileMode.OpenOrCreate);
                    BinaryFormatter bf = new BinaryFormatter();
                    bf.Serialize(fs, hash);
                    fs.Close();
                }
                catch
                {
                    MessageBox.Show("保存设置失败!", "失败", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
            }
            this.Hide();
        }

        Hashtable hash = new Hashtable();
        void hook_OnKeyDownEvent(object sender, KeyEventArgs e)
        {                    
            if (isHookEnable)
            {
                IntPtr war3 = User32Api.FindWindow(null, "Warcraft III");
                if (war3 != null)
                {
                    this.label6.Text = "软件已启用";
                    if (war3 != IntPtr.Zero)
                    {
                        User32Api.SetForegroundWindow(war3);
                        if (checkBox1.Checked)
                            User32Api.SendMessage(war3, WM_KEYDOWN, KEY_QUOTLEFT, 0);//按下[,可显示友方单位生命值
                        if (checkBox2.Checked)
                            User32Api.SendMessage(war3, WM_KEYDOWN, KEY_QUOTRIGHT, 0);//按下],可显示友方单位生命值
                        if (hash.ContainsKey(e.KeyValue.ToString()))
                        {
                            User32Api.SendMessage(war3, WM_KEYDOWN, int.Parse(hash[e.KeyValue.ToString()].ToString()), 0);
                            User32Api.SendMessage(war3, WM_KEYUP, int.Parse(hash[e.KeyValue.ToString()].ToString()), 0);
                        }
                    }
                }
                else {
                    this.label6.Text = "软件未启用";
                }
              
            }
        }
        //关闭或最小化时隐藏
        protected override void WndProc(ref Message m)
        {
            const int WM_SYSCOMMAND = 0x0112;
            const int SC_CLOSE = 0xF060;
            const int SC_MINIMIZE = 0xF020;
            if (m.Msg == WM_SYSCOMMAND && ((int)m.WParam == SC_MINIMIZE || (int)m.WParam == SC_CLOSE))
            {
                //最小化到系统栏 
                this.Hide();
                return;
            }
            base.WndProc(ref m);
        }

        private void notifyIcon1_DoubleClick(object sender, EventArgs e)
        {
            this.Show();
        }       

    }
}
